﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Zhao.Common.Helper;

namespace Zhao.IServer
{
    public interface IBaseService<TEntity> where TEntity : class
    {
        #region 同步

        #region 查询
        /// <summary>
        /// 根据主键获取一条数据，primaryKey必须为主键
        /// </summary>
        /// <param name="primaryKey">主键</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns>TEntity</returns>
        TEntity Query<T>(T primaryKey, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式获取一条数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns>TEntity</returns>
        TEntity Query(Expression<Func<TEntity, bool>> expression, bool blnUseCache = false);

        TEntity QueryOrder(Expression<Func<TEntity, bool>> expression, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式取数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="strOrderByFileds">排序</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns></returns>
        List<TEntity> QueryList(Expression<Func<TEntity, bool>> expression, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式取数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="strOrderByFileds">排序</param>
        /// <param name="top">前几条</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns></returns>
        List<TEntity> QueryList(Expression<Func<TEntity, bool>> expression, int top, string strOrderByFileds = null, bool blnUseCache = false);

        PageModel<TEntity> QueryPage(Expression<Func<TEntity, bool>> where, string strOrderByFileds = null, int intPageIndex = 1, int intPageSize = 20);

        int QueryCount(Expression<Func<TEntity, bool>> whereExpression);

        #endregion

        #region 添加

        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>int</returns>
        int Add(TEntity entity);

        /// <summary>
        /// 批量添加数据
        /// </summary>
        /// <param name="entities">List<T></param>
        /// <returns>int</returns>
        int Add(List<TEntity> entities);

        #endregion

        #region 修改

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>bool</returns>
        bool Update(TEntity entity);

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="columns">指定列表达式</param>
        /// <param name="where">条件表达式</param>
        /// <returns>bool</returns>
        bool Update(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> where);

        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="entities">entities</param>
        /// <returns>int</returns>
        int Update(List<TEntity> entities);
        #endregion

        #region 删除

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="primaryKey">主键</param>
        /// <returns>bool</returns>
        bool Delete<T>(T primaryKey);

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>bool</returns>
        bool Delete(TEntity entity);

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="primaryKeys">主键集合</param>
        /// <returns>int</returns>
        int Delete(object[] primaryKeys);

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="where">条件表达式</param>
        /// <returns>int</returns>
        int Delete(Expression<Func<TEntity, bool>> where);

        #endregion

        #endregion

        #region 异步

        #region 查询
        /// <summary>
        /// 根据主键获取一条数据，primaryKey必须为主键
        /// </summary>
        /// <param name="primaryKey">主键</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns>TEntity</returns>
        Task<TEntity> QueryAsync<T>(T primaryKey, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式获取一条数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns>TEntity</returns>
        Task<TEntity> QueryAsync(Expression<Func<TEntity, bool>> expression, bool blnUseCache = false);

        Task<TEntity> QueryOrderAsync(Expression<Func<TEntity, bool>> expression, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式取数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="strOrderByFileds">排序</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryListAsync(Expression<Func<TEntity, bool>> expression, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式取数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="strOrderByFileds">排序</param>
        /// <param name="top">前几条</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryListAsync(Expression<Func<TEntity, bool>> expression, int top, string strOrderByFileds = null, bool blnUseCache = false);

        Task<PageModel<TEntity>> QueryPageAsync(Expression<Func<TEntity, bool>> where, string strOrderByFileds = null, int intPageIndex = 1, int intPageSize = 20);


        /// <summary>
        /// 查询数量
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        Task<int> QueryCountAsync(Expression<Func<TEntity, bool>> whereExpression);
        #endregion

        #region 添加

        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>int</returns>
        Task<int> AddAsync(TEntity entity);

        /// <summary>
        /// 批量添加数据
        /// </summary>
        /// <param name="entities">List<T></param>
        /// <returns>int</returns>
        Task<int> AddAsync(List<TEntity> entities);

        #endregion

        #region 修改

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>bool</returns>
        Task<bool> UpdateAsync(TEntity entity);

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="columns">指定列表达式</param>
        /// <param name="where">条件表达式</param>
        /// <returns>bool</returns>
        Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> where);

        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="entities">entities</param>
        /// <returns>int</returns>
        Task<int> UpdateAsync(List<TEntity> entities);
        #endregion

        #region 删除

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="primaryKey">主键</param>
        /// <returns>bool</returns>
        Task<bool> DeleteAsync<T>(T primaryKey);

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>bool</returns>
        Task<bool> DeleteAsync(TEntity entity);

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="primaryKeys">主键集合</param>
        /// <returns>int</returns>
        Task<int> DeleteAsync(object[] primaryKeys);

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="where">条件表达式</param>
        /// <returns>int</returns>
        Task<int> DeleteAsync(Expression<Func<TEntity, bool>> where);

        #endregion

        #endregion
    }
}
